<script setup lang="ts">
import AppTable from "@/components/app/AppTable.vue";
import {ref, onMounted} from "vue";
import {createMenu, updateMenu, deleteMenuByMenuId, getMenuByMenuId, listAllMenus} from "@/api/system";
import {confirm, alertSuccess, alertError} from "@/utils/alert";
import type {ISysMenuDTO} from "@/types";
import {
  ElMessage,
  ElForm,
  ElFormItem,
  ElInput,
  ElSelect,
  ElOption,
  ElSwitch,
  ElInputNumber,
  ElRadioGroup,
  ElRadioButton,
  ElPopover,
  ElButton
} from "element-plus";
import type {FormInstance, FormRules} from "element-plus";

// 导入常用图标
import {
  Setting,
  DataBoard,
  HomeFilled,
  View,
  Menu,
  Memo,
  User,
  Key,
  Promotion,
  DataAnalysis,
  Document,
  Search,
  Edit,
  Delete,
  Plus,
  Star,
  ChatLineRound,
  Bell,
  Location,
  Phone,
  Message,
  Goods,
  Tickets,
  Reading,
  Files,
  Notebook,
  CreditCard,
  Histogram,
  Help,
  Warning,
  InfoFilled,
  CircleCheck,
  CircleClose
} from "@element-plus/icons-vue";

defineOptions({
  name: "SysMenu"
})

const tableRef = ref()
const dialogVisible = ref(false)
const dialogTitle = ref('')
const formType = ref<'create' | 'update'>('create')
const formRef = ref<FormInstance>()
const currentRow = ref<any>({})
const menuOptions = ref<any[]>([])

// 常用图标列表
const iconList = [
  'Setting', 'DataBoard', 'HomeFilled', 'View', 'Menu', 'Memo', 'User', 'Key',
  'Promotion', 'DataAnalysis', 'Document', 'Search', 'Edit', 'Delete', 'Plus',
  'Star', 'ChatLineRound', 'Bell', 'Location', 'Phone', 'Message', 'Goods',
  'Tickets', 'Reading', 'Files', 'Notebook', 'CreditCard', 'Histogram', 'Help',
  'Warning', 'InfoFilled', 'CircleCheck', 'CircleClose'
];

// 图标映射对象
const iconMap = {
  Setting,
  DataBoard,
  HomeFilled,
  View,
  Menu,
  Memo,
  User,
  Key,
  Promotion,
  DataAnalysis,
  Document,
  Search,
  Edit,
  Delete,
  Plus,
  Star,
  ChatLineRound,
  Bell,
  Location,
  Phone,
  Message,
  Goods,
  Tickets,
  Reading,
  Files,
  Notebook,
  CreditCard,
  Histogram,
  Help,
  Warning,
  InfoFilled,
  CircleCheck,
  CircleClose,
};

// 表单数据（扩展 ISysMenuDTO 类型以包含 menuId）
const formData = ref<ISysMenuDTO & { menuId?: number }>({
  menuId: undefined,
  menuName: '',
  parentId: 0,
  orderNum: 0,
  path: '',
  component: '',
  query: '',
  routeName: '',
  isFrame: 1,
  isCache: 0,
  menuType: 'M', // 设置默认值为目录类型
  visible: '0',
  status: '0',
  perms: '',
  icon: '',
  remark: ''
})

// 表单验证规则
const formRules = ref<FormRules>({
  menuName: [
    {required: true, message: '请输入菜单名称', trigger: 'blur'}
  ],
  orderNum: [
    {required: true, message: '请输入显示顺序', trigger: 'blur'}
  ],
  routeName: [
    {required: true, message: '请输入路由名称', trigger: 'blur'}
  ],
  path: [
    {required: true, message: '请输入路由地址', trigger: 'blur'}
  ],
  menuType: [
    {required: true, message: '请选择菜单类型', trigger: 'change'}
  ],
  icon: [
    {required: true, message: '请选择菜单图标', trigger: 'blur'}
  ]
})

// 获取所有菜单列表
const getMenuList = () => {
  tableRef.value.queryData()
}

// 将树形结构数据扁平化为数组
const flattenMenuTree = (menuTree: any[], level = 0) => {
  const result: any[] = [];
  const prefix = '　'.repeat(level); // 使用全角空格作为前缀

  menuTree.forEach(menu => {
    result.push({
      menuId: menu.menuId,
      menuName: prefix + menu.menuName,
      parentId: menu.parentId || 0
    });

    // 递归处理子菜单
    if (menu.children && menu.children.length > 0) {
      result.push(...flattenMenuTree(menu.children, level + 1));
    }
  });

  return result;
};

// 获取菜单选项列表
const getMenuOptions = async () => {
  try {
    // 使用已有的API方法获取菜单数据
    const result = await listAllMenus();

    if (result && result.data && result.data.length > 0) {
      // 将树形结构扁平化为选项列表
      const flatOptions = flattenMenuTree(result.data);
      menuOptions.value = [
        { menuId: 0, menuName: '主类目' },
        ...flatOptions
      ];
    } else {
      // 如果没有数据，至少保留主类目
      menuOptions.value = [{ menuId: 0, menuName: '主类目' }];
    }
  } catch (error) {
    console.error('获取菜单选项失败:', error);
    // 出错时至少保留主类目
    menuOptions.value = [{ menuId: 0, menuName: '主类目' }];
  }
}

// 打开弹窗
const openDialog = (type: 'create' | 'update', row?: any) => {
  formType.value = type
  dialogTitle.value = type === 'create' ? '添加菜单' : '修改菜单'

  if (type === 'update' && row) {
    // 编辑时填充表单数据
    Object.assign(formData.value, row)
    currentRow.value = row
  } else {
    // 新增时重置表单
    resetForm()
    if (row && row.menuId) {
      // 如果是添加子菜单，设置父级ID
      formData.value.parentId = row.menuId
    }
  }

  // 加载菜单选项
  getMenuOptions()
  dialogVisible.value = true
}

// 重置表单
const resetForm = () => {
  formData.value = {
    menuId: undefined,
    menuName: '',
    parentId: 0,
    orderNum: 0,
    path: '',
    component: '',
    query: '',
    routeName: '',
    isFrame: 1,
    isCache: 0,
    menuType: 'M', // 设置默认值为目录类型
    visible: '0',
    status: '0',
    perms: '',
    icon: '',
    remark: ''
  }
  currentRow.value = {}
}

// 选择图标
const selectIcon = (iconName: string) => {
  formData.value.icon = iconName;
};

// 提交表单
const submitForm = async () => {
  if (!formRef.value) return
  await formRef.value.validate(async (valid) => {
    if (valid) {
      try {
        if (formType.value === 'create') {
          await createMenu(formData.value)
          ElMessage.success('创建成功')
        } else {
          await updateMenu(formData.value.menuId!, formData.value)
          ElMessage.success('修改成功')
        }
        dialogVisible.value = false
        getMenuList()
      } catch (error: any) {
      }
    }
  })
}

// 删除菜单
const handleDelete = async (id: number) => {
  try {
    // 先获取菜单信息用于回显
    const res = await getMenuByMenuId(id)
    if (res.data) {
      const menuName = res.data.menuName
      await confirm(`确定要删除菜单"${menuName}"吗？`, async () => {
        await deleteMenuByMenuId(id)
        alertSuccess('删除成功')
        getMenuList()
      })
    }
  } catch (error: any) {
  }
}

// 关闭弹窗
const handleClose = () => {
  dialogVisible.value = false
  resetForm()
}

// 组件挂载时获取菜单选项
onMounted(() => {
  getMenuOptions()
})
</script>

<template>
  <div>
    <AppTable
      title="菜单管理"
      ref="tableRef"
      row-key="menuId"
      :btn-show="{
        add: true,
        edit: false,
        delete: false,
        export:false,
        import:false
      }"
      :pageable="false"
      api-method="get"
      api-path="/api/sys/menu/listAll"
      @multiple-selection="data => {console.log( data)}"
      @handle-btn-click="()=>openDialog('create')"
    >
      <template v-slot:actionBar>
      </template>
      <template v-slot:tableColumn>
        <el-table-column prop="menuName" label="菜单名称"/>
        <el-table-column label="图标" align="center" width="100">
          <template #default="scope">
            <el-icon v-if="scope.row.icon">
              <component :is="iconMap[scope.row.icon as keyof typeof iconMap] || scope.row.icon"/>
            </el-icon>
          </template>
        </el-table-column>
        <el-table-column prop="path" label="路径" align="left"/>
        <el-table-column prop="component" label="组件路径" align="left"/>
        <el-table-column label="状态" align="center" width="100">
          <template #default="scope">
            <el-button link
                      :type="scope.row.status == '0' ? 'success' : 'danger'">
                    {{ scope.row.status == '0' ? '启用' : '禁用' }}
                    </el-button>
          </template>
        </el-table-column>
        <el-table-column prop="orderNum" label="排序" align="center" width="100"/>
        <el-table-column fixed="right" label="操作" width="250">
          <template #default="scope">
            <el-button link type="primary" size="small" icon="Edit"
                       @click="openDialog('update', scope.row)">
              编辑
            </el-button>
            <el-button link type="primary" size="small" icon="CirclePlusFilled"
                       @click="openDialog('create', scope.row)">
              新增
            </el-button>
            <el-button link type="danger" size="small" icon="Delete"
                       @click="handleDelete(scope.row.menuId)">
              删除
            </el-button>
          </template>
        </el-table-column>
      </template>
    </AppTable>

    <!-- 菜单编辑弹窗 -->
    <el-dialog
      :title="dialogTitle"
      v-model="dialogVisible"
      width="700px"
      @close="handleClose"
    >
      <el-form
        ref="formRef"
        :model="formData"
        :rules="formRules"
        label-width="100px"
      >
        <el-row :gutter="20">
          <!-- 基本信息 -->
          <el-col :span="12">
            <el-form-item label="菜单名称" prop="menuName">
              <el-input v-model="formData.menuName" placeholder="请输入菜单名称"/>
            </el-form-item>
          </el-col>

          <el-col :span="12">
            <el-form-item label="菜单类型" prop="menuType">
              <el-radio-group v-model="formData.menuType">
                <el-radio-button label="M">目录</el-radio-button>
                <el-radio-button label="C">菜单</el-radio-button>
                <el-radio-button label="F">按钮</el-radio-button>
              </el-radio-group>
            </el-form-item>
          </el-col>

          <el-col :span="12">
            <el-form-item label="上级菜单" prop="parentId">
              <el-select v-model="formData.parentId" placeholder="请选择上级菜单" style="width: 100%">
                <el-option
                  v-for="item in menuOptions"
                  :key="item.menuId"
                  :label="item.menuName"
                  :value="item.menuId"
                />
              </el-select>
            </el-form-item>
          </el-col>

          <el-col :span="12">
            <el-form-item label="显示排序" prop="orderNum">
              <el-input-number v-model="formData.orderNum" controls-position="right" :min="0" style="width: 100%"/>
            </el-form-item>
          </el-col>

          <!-- 路由信息 -->
          <el-col :span="12">
            <el-form-item label="路由地址" prop="path">
              <el-input v-model="formData.path" placeholder="请输入路由地址"/>
            </el-form-item>
          </el-col>

          <el-col :span="12">
            <el-form-item label="路由名称" prop="routeName">
              <el-input v-model="formData.routeName" placeholder="请输入路由名称"/>
            </el-form-item>
          </el-col>

          <el-col :span="12">
            <el-form-item label="组件路径" prop="component">
              <el-input v-model="formData.component" placeholder="请输入组件路径"/>
            </el-form-item>
          </el-col>

          <el-col :span="12">
            <el-form-item label="路由参数" prop="query">
              <el-input v-model="formData.query" placeholder="请输入路由参数"/>
            </el-form-item>
          </el-col>

          <!-- 图标选择 -->
          <el-col :span="12">
            <el-form-item label="菜单图标" prop="icon">
              <el-popover
                placement="bottom-start"
                :width="600"
                trigger="click"
              >
                <template #reference>
                  <el-input
                    v-model="formData.icon"
                    placeholder="请选择菜单图标"
                    readonly
                    style="cursor: pointer;"
                  >
                    <template #prepend>
                      <el-icon v-if="formData.icon">
                        <component :is="iconMap[formData.icon as keyof typeof iconMap] || formData.icon"/>
                      </el-icon>
                    </template>
                  </el-input>
                </template>

                <div class="icon-selector">
                  <div class="icon-grid">
                    <div
                      v-for="iconName in iconList"
                      :key="iconName"
                      class="icon-item"
                      :class="{ active: formData.icon === iconName }"
                      @click="selectIcon(iconName)"
                    >
                      <el-icon>
                        <component :is="iconMap[iconName as keyof typeof iconMap]"/>
                      </el-icon>
                      <span class="icon-name">{{ iconName }}</span>
                    </div>
                  </div>
                </div>
              </el-popover>
            </el-form-item>
          </el-col>

          <!-- 权限信息 -->
          <el-col :span="12">
            <el-form-item label="权限标识" prop="perms">
              <el-input v-model="formData.perms" placeholder="请输入权限标识"/>
            </el-form-item>
          </el-col>

          <!-- 状态设置 -->
          <el-col :span="12">
            <el-form-item label="菜单状态" prop="status">
              <el-switch
                v-model="formData.status"
                active-value="0"
                inactive-value="1"
                active-text="启用"
                inactive-text="禁用"
              />
            </el-form-item>
          </el-col>

          <el-col :span="12">
            <el-form-item label="显示状态" prop="visible">
              <el-switch
                v-model="formData.visible"
                active-value="0"
                inactive-value="1"
                active-text="显示"
                inactive-text="隐藏"
              />
            </el-form-item>
          </el-col>

          <el-col :span="12">
            <el-form-item label="是否外链" prop="isFrame">
              <el-switch
                v-model="formData.isFrame"
                :active-value="0"
                :inactive-value="1"
                active-text="是"
                inactive-text="否"
              />
            </el-form-item>
          </el-col>

          <el-col :span="12">
            <el-form-item label="是否缓存" prop="isCache">
              <el-switch
                v-model="formData.isCache"
                :active-value="0"
                :inactive-value="1"
                active-text="缓存"
                inactive-text="不缓存"
              />
            </el-form-item>
          </el-col>

          <!-- 备注 -->
          <el-col :span="24">
            <el-form-item label="备注" prop="remark">
              <el-input v-model="formData.remark" type="textarea" placeholder="请输入备注" :rows="3"/>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="handleClose">取 消</el-button>
          <el-button type="primary" @click="submitForm">确 定</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped>
.dialog-footer {
  text-align: right;
}

.icon-selector {
  max-height: 300px;
  overflow-y: auto;
}

.icon-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 10px;
}

.icon-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 8px;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s;
  border: 1px solid #ebeef5;
}

.icon-item:hover {
  background-color: #f5f7fa;
  border-color: #409eff;
}

.icon-item.active {
  background-color: #ecf5ff;
  border-color: #409eff;
}

.icon-item .el-icon {
  font-size: 20px;
  margin-bottom: 4px;
}

.icon-name {
  font-size: 12px;
  text-align: center;
  word-break: break-all;
}
</style>
